use crate::{mdb, code};
use axum::Json;
use mongodb::{options::{GridFsBucketOptions, GridFsUploadOptions }, bson::doc, , gridfs::{ FilesCollectionDocument, GridFsBucket }};
use serde_json::Value;

use super::gridfs_delete::delete_by_bson;
// 获取文件内容
pub async fn move_file(filename:&str, bucket_name:&str ) -> Result<(), Json<Value>>{
    let conn = mdb::connect().await?;
    // 目标桶
    let dest_options = GridFsBucketOptions::builder().bucket_name(bucket_name.to_string()).build();
    let dest_bucket = conn.gridfs_bucket(dest_options);
    let cursor = dest_bucket.find(doc! {"filename":filename}).await;
    if cursor.is_ok() {
        let mut rs = cursor.unwrap();
        if rs.advance().await.unwrap_or_default() {
            return Ok(())
        }
    }
    // 从一个桶下载文件
    let options = GridFsBucketOptions::builder().build();
    let bucket = conn.gridfs_bucket(options);
    let doc = get_file(bucket.to_owned(), filename).await?;
    match bucket.open_download_stream_by_name(filename).await {
        Ok(stream) => {
            // 将下载文件移入到新的桶
            let meta = match doc.metadata {
                Some(mut f) => {
                    f.insert("temp", false);
                    Some(f)
                },
                None => None
            };
            let reader_options = GridFsUploadOptions::builder().metadata(meta).build();
            let reader = dest_bucket.upload_from_futures_0_3_reader(
                doc.filename.unwrap_or_default(),
                stream,
                reader_options
            ).await;
            match reader {
                Ok(_f) => {
                    delete_by_bson(doc.id, "fs").await?;
                    Ok(())
                },
                Err(e) => Err(code::sys_(e.to_string()))
            }
        },
        Err(e) => Err(code::sys_(e.to_string()))
    } 
}
// 查找文件，获取文件信息
pub(self) async fn get_file(bucket:GridFsBucket, filename:&str) -> Result<FilesCollectionDocument, Json<Value>>{
    let rs = bucket.find(doc!{"filename":filename}, None).await;
    match rs {
        Ok(mut d) => {
            let has_data = d.advance().await.unwrap_or_default();
            if has_data {
                let rs = d.deserialize_current();
                match rs {
                    Ok(f) => {
                        Ok( f )
                    },
                    Err(e) => Err(code::sys_(e.to_string()))
                }
            }else{
                Err(code::sys_(filename.to_string() + "文件未上传，请先上传文件！"))
            }
        },
        Err(e) => Err(code::sys_(e.to_string()))
    }
}